using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Estructuras.Comunes
{
    public static class Comunes
    {
        /// <summary>
        /// Obtiene un TextReader a partir del fichero de entrada indicado.
        /// </summary>
        /// <param name="entrada">Fichero de entrada de datos</param>
        /// <returns>Stream de datos</returns>
        public static TextReader ObtenerEntrada(string entrada)
        {
            TextReader entradaDatos;
            if ("std".Equals(entrada))
            {
                // entrada estandard
                try
                {
                    entradaDatos = Console.In;
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorAsignarEntradaStd);
                }
            }
            else
            {
                // entrada fichero
                try
                {
                    entradaDatos = (TextReader)new StreamReader(entrada, Encoding.Default);
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorAbrirEntradaDatos);
                }
            }
            return entradaDatos;
        }

        /// <summary>
        /// Obtiene un TextWriter a partir del fichero de salida indicado.
        /// </summary>
        /// <param name="salida">Fichero de salida de datos</param>
        /// <returns>Stream de datos</returns>
        public static TextWriter ObtenerSalida(string salida)
        {
            TextWriter salidaDatos;
            if ("std".Equals(salida))
            {
                // salida estandard
                try
                {
                    salidaDatos = Console.Out;
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorAsignarSalidaStd);
                }
            }
            else
            {
                // salida fichero
                try
                {
                    salidaDatos = (TextWriter)new StreamWriter(salida, false, Encoding.Default);
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorAbrirSalidaDatos);
                }
            }
            return salidaDatos;
        }

        /// <summary>
        /// Cierra el flujo de entrada de datos.
        /// </summary>
        /// <param name="entrada">Flujo de entrada de datos</param>
        /// <param name="nombreEntrada">Nombre del fichero de entrada de datos</param>
        public static void CerrarEntrada(TextReader entrada, string nombreEntrada)
        {
            if ("std".Equals(nombreEntrada))
            {
                // entrada estandard
                try
                {
                    StreamReader sr = new StreamReader(Console.OpenStandardInput(), Encoding.Default);
                    Console.SetIn(sr);
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorReasignarEntradaStd);
                }
            }
            else
            {
                // entrada fichero
                try
                {
                    entrada.Close();
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorCerrarFichero + nombreEntrada);
                }
            }
        }

        /// <summary>
        /// Cierra el flujo de salida de datos.
        /// </summary>
        /// <param name="salida">Flujo de salida de datos</param>
        /// <param name="nombreSalida">Nombre del fichero de salida de datos</param>
        public static void CerrarSalida(TextWriter salida, string nombreSalida)
        {
            if ("std".Equals(nombreSalida))
            {
                // entrada estandard
                try
                {
                    StreamWriter sw = new StreamWriter(Console.OpenStandardOutput(), Encoding.Default);
                    sw.AutoFlush = true;
                    Console.SetOut(sw);
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorReasignarSalidaStd);
                }
            }
            else
            {
                // entrada fichero
                try
                {
                    salida.Close();
                }
                catch (Exception)
                {
                    throw new Excepcion(Constantes.MensajeErrorCerrarFichero + nombreSalida);
                }
            }
        }
    }
}
